from selenium.webdriver import ActionChains
from selenium import webdriver
from selenium.webdriver.common.by import By

import requests
from lxml import etree
import re
import time
import random

import asyncio
from concurrent.futures import ThreadPoolExecutor
from queue import Queue

import pyautogui

from pyecharts import options as opts
from pyecharts.charts import Map

def get_tracks(distance):
    v = 0
    t = 0.3
    tracks = []
    current = 0
    mid = distance*4/5
    while current < distance:
        if current < mid:
            a = 2
        else:
            a = -3
        v0 = v
        s = v0* t + 0.5 * a *(t ** 2)
        current += s
        tracks.append(round(s))
        v = v0 + a*t
    return tracks


def get_cookies(url):
    options = webdriver.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("--headless")
    driver = webdriver.Chrome(options=options)
    driver.maximize_window()
    with open('stealth.min.js') as f:
        js = f.read()
    # 读取js
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": js
    })
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
    })
    driver.get(
        "https://login.taobao.com/member/login.jhtml?spm=a21bo.jianhua.754894437.1.5af911d9wAnjLD&f=top&redirectURL=https%3A%2F%2Fwww.taobao.com%2F")
    name = driver.find_element(By.XPATH, "//input[@name='fm-login-id']")
    name.send_keys(USERNAME)
    password = driver.find_element(By.XPATH, value="//input[@name='fm-login-password']")
    password.send_keys(PASSWORD)
    time.sleep(random.uniform(3, 4))
    try:
        driver.switch_to.frame(0)
    except:
        pass
    action = ActionChains(driver)
    try:
        span = driver.find_element(By.XPATH, "//span[@id='nc_1_n1z']")
        action.click_and_hold(span)
        action.move_by_offset(240, 0)
        tracks = get_tracks(20)
        for i in tracks:
            action.move_by_offset(i, 0)
        action.release(span)
        action.perform()
    except:
        pass
    login = driver.find_element(By.XPATH, value="//button[@class='fm-button fm-submit password-login']")
    action.click(login)
    action.perform()
    time.sleep(random.uniform(2, 3))
    driver.get(url)
    time.sleep(random.uniform(2, 3))
    # if check(driver.page_source):
    #     pos = pyautogui.locateCenterOnScreen('a.png')
    #     while True:
    #         # span = driver.find_element(By.XPATH, value="//span[@id='nc_1_n1z']")
    #         # div_f = driver.find_element(By.XPATH, value="//div[@id='nc_1__scale_text']")
    #         # action.click_and_hold(span)
    #         # action.move_by_offset(240, 0)
    #         # time.sleep(random.uniform(2, 3))
    #         # tracks = get_tracks(20)
    #         # for i in tracks:
    #         #     try:
    #         #         action.move_by_offset(i, 0)
    #         #         action.pause(0.5)
    #         #     except:
    #         #         break
    #         # time.sleep(random.uniform(1, 2))
    #
    #         pyautogui.moveTo(pos, duration=random.uniform(0.1, 0.9))
    #         pyautogui.mouseDown()
    #         pyautogui.moveRel(random.uniform(110, 160), random.randint(-20, 20), duration=random.uniform(0.1, 0.9))
    #         pyautogui.moveRel(random.uniform(130, 180), random.randint(-20, 20), duration=random.uniform(0.1, 0.9))
    #         time.sleep(2)
    #         pyautogui.mouseUp()
    #
    #         try:
    #             warning = driver.find_element(By.XPATH, value="//div[@id='nc_1_wrapper']")
    #             pyautogui.moveRel(random.uniform(-50, -150), random.randint(-10, 10), duration=random.uniform(0.1, 0.9))
    #             pyautogui.click()
    #             # action.click(warning).perform()
    #         except:
    #             print('跳出')
    #             break
    # time.sleep(random.uniform(2, 3))
    cookies = {
        'enc': '64x6vlq%2BWx%2F59Wou6CUlRF3LtOp%2F6y%2F%2BfqTDxEG65rnO33iMsRTaeTafOPBHofUjINJ23c2YfXWXz5TzR%2FbwWg%3D%3D',
        'thw': 'cn',
        't': '971f3773dea5f8107b4e531d1763711a',
        'xlly_s': '1',
        'cna': 'MhN8GoXwrjYCAXZxOr7o/9xT',
        'sgcookie': 'E100hEdfbsXaRa1XYGxc%2BLcDnBVBNu8yJKlyXLdxU8xMqJ20WZMAs28mCunMhw6ILMRcQfUlHjvAYiyfgsgieI0UtCGfS7R1UhQ6cqsRrcWlPtHIVARJphKQtZ4kym4pSmoe',
        'uc3': 'vt3=F8dCvCtKeIh4O7h7t9k%3D&nk2=DHEJKLVmXbk%3D&lg2=W5iHLLyFOGW7aA%3D%3D&id2=UUGk3pfED%2Bgvag%3D%3D',
        'lgc': 'o%5Cu84DD%5Cu4E66%5Cu7B7Eo',
        'uc4': 'id4=0%40U2OT7jgbutfqdz4b9uSkN4OScfvV&nk4=0%40DmY589XWs7QYv6X4Bptpjp0jrQ%3D%3D',
        'tracknick': 'o%5Cu84DD%5Cu4E66%5Cu7B7Eo',
        '_cc_': 'Vq8l%2BKCLiw%3D%3D',
        'mt': 'ci=-1_0',
        '_m_h5_tk': '69c9c59c51aafb33573d2a54747e97f6_1649097463456',
        '_m_h5_tk_enc': 'b1f2e1248a29102650d9ddd21fb67e24',
        'uc1': 'cookie14=UoewCZQLqKR0Wg%3D%3D',
        '_tb_token_': 'e345b9037e6e6',
        'x5sec': '7b227365617263686170703b32223a223761373662303135326664656435316438613330643762666232366438313161434f7573724a4947454b366e7659666f2b73374b61526f4d4d6a6b324d4441304d6a55784d54737a4d4b6546677037382f2f2f2f2f77453d227d',
        'JSESSIONID': 'E0D56FBD88B5126591707A878470725D',
        'isg': 'BEpKM_43HM7nepAp2JncATvVmzDsO86VGvJlKNSBDB8Yh-xBt8qIpd-xl_Nbd0Yt',
        'l': 'eBaDtjdHLQTHbMW3BO5Zlurza77TXQRfhsPzaNbMiInca6MRK_pgSNC3sJp9jdtjgtCbvU-PqhPt0RE68Gadg2HvCbKrCyConxvO.',
        'tfstk': 'cqtdBPgxYfcHDqW93e3MNyTPVKWRa0cR1J1u2ADB9wFga7Z_XsxDmnhyL265g6HO.',
    }

    for cookie in driver.get_cookies():
        cookies[cookie['name']] = cookie['value']
    return cookies

def check(html):
    if '霸下通用 web 页面-验证码' in html:
        return True
    return False

def get_next_data(url):
    headers = {
        'authority': 's.taobao.com',
        'accept': '*/*',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        # Requests sorts cookies= alphabetically
        # 'cookie': 'enc=64x6vlq%2BWx%2F59Wou6CUlRF3LtOp%2F6y%2F%2BfqTDxEG65rnO33iMsRTaeTafOPBHofUjINJ23c2YfXWXz5TzR%2FbwWg%3D%3D; thw=cn; t=971f3773dea5f8107b4e531d1763711a; xlly_s=1; cna=MhN8GoXwrjYCAXZxOr7o/9xT; sgcookie=E100hEdfbsXaRa1XYGxc%2BLcDnBVBNu8yJKlyXLdxU8xMqJ20WZMAs28mCunMhw6ILMRcQfUlHjvAYiyfgsgieI0UtCGfS7R1UhQ6cqsRrcWlPtHIVARJphKQtZ4kym4pSmoe; uc3=vt3=F8dCvCtKeIh4O7h7t9k%3D&nk2=DHEJKLVmXbk%3D&lg2=W5iHLLyFOGW7aA%3D%3D&id2=UUGk3pfED%2Bgvag%3D%3D; lgc=o%5Cu84DD%5Cu4E66%5Cu7B7Eo; uc4=id4=0%40U2OT7jgbutfqdz4b9uSkN4OScfvV&nk4=0%40DmY589XWs7QYv6X4Bptpjp0jrQ%3D%3D; tracknick=o%5Cu84DD%5Cu4E66%5Cu7B7Eo; _cc_=Vq8l%2BKCLiw%3D%3D; _m_h5_tk=20c3002e4854ec915df6017934d21ac0_1649071475015; _m_h5_tk_enc=490c8d72d9caf1bda899eadf8989fac8; mt=ci=-1_0; uc1=cookie14=UoewCZQFk7bxTQ%3D%3D; _tb_token_=e5fbe3e67e8b5; x5sec=7b227365617263686170703b32223a223639646233356631336461313566363765373465303832373864356664663165434d376b71704947454f714f78724b546a366a5877414561444449354e6a41774e4449314d5445374d54436e68594b652f502f2f2f2f3842227d; JSESSIONID=D973ACE6ED7B3AAFA5403EF76B6D7E99; tfstk=cY3lBQZiH0r5HzqmfUaSg6M6J2vAZtQUI2ujuVBR3Pyi670VitsVb4J6i8v6UM1..; l=eBaDtjdHLQTHbqHwBO5anurza77OmIObzsPzaNbMiInca6MfTpKgbNC3_FpM7dtjgt5xweKPqhPt0RUH8vUU-xgKqelyRs5mppp6Re1..; isg=BL29S58pg5bZaCewM9iTyNBEzBm3WvGsIcNykX8D9pSFtt_oRquBfXEgYOrwNglk',
        'referer': 'https://s.taobao.com/search?q=%E5%85%85%E7%94%B5%E5%AE%9D&suggest=history_2&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.jianhua.201856-taobao-item.2&ie=utf8&initiative_id=tbindexz_20170306&_input_charset=utf-8&wq=&suggest_query=&source=suggest',
        'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Microsoft Edge";v="100"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'script',
        'sec-fetch-mode': 'no-cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36 Edg/100.0.1185.29',
    }

    response = requests.get(url, headers=headers, cookies=cookies)
    return get_data(response)

def get_data(response):
    r = re.compile(r"g_page_config = (.*\});")
    try:
        d = eval(r.search(response.text).groups(0)[0].replace('true', 'True').replace('false', 'False'))
        return d
    except:
        print(response.text)

def get_loction(d:dict):
    if d:
        loction_ls = [i['item_loc'] for i in d['mods']['itemlist']['data']['auctions']]
        return loction_ls
    else:
        print(None)

def get_url_ls(q, page_number):
    url_ls = []
    next_page_url = 'https://s.taobao.com/search?q={}&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20220404&ie=utf8&bcoffset={}&ntoffset={}&p4ppushleft=2%2C48&s={}'
    s = 0
    for i in range(page_number):
        if i % 2:
            n_u = next_page_url.format(q, -i, -i, s)
        else:
            n_u = next_page_url.format(q, i, i, s)
        s += 44
        url_ls.append(n_u)
    return url_ls

def get_result(future):
    dq.put(get_loction(future.result()))

def run(ls:list, func):
    tasks = []
    loop = asyncio.get_event_loop()
    executor = ThreadPoolExecutor(25)
    for link in ls:
        future = loop.run_in_executor(executor, func, link)
        tasks.append(future)
        future.add_done_callback(get_result)
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

def create_china_map(title):
 '''
  作用：生成中国地图
 '''
 (
  Map()
   .add(
   series_name="店数",
   data_pair=monster,
   maptype="china",)
   # 设定标题
   .set_global_opts(title_opts=opts.TitleOpts(title=title),
                    visualmap_opts=opts.VisualMapOpts(max_=50, is_piecewise=True))


   # 生成本地html档案
   .render(f"{title}.html")

 )

if __name__ == "__main__":
    keyword = input("请输入要查询的商品:")
    USERNAME = '' # 用户名
    PASSWORD = '' # 密码
    url_ls = get_url_ls(keyword, 20)
    cookies = get_cookies(url_ls[0])
    dq = Queue()
    loction_ls = []
    run(url_ls, get_next_data)
    while dq.qsize():
        loction_ls.extend(dq.get())
    d = dict()
    for i in loction_ls:
        d[i.split()[0]] = d.get(i.split()[0], 0) + 1
    monster = [[k, v] for k, v in d.items()]
    create_china_map("淘宝{}店家全国分布图".format(keyword))

